package com.yookey.study.presenter;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.view.View;

import com.base.asrwake.dialog.BaiduASRDigitalDialog;
import com.base.asrwake.dialog.DigitalDialogInput;
import com.base.asrwake.inputstream.InFileStream;
import com.base.asrwake.params.CommonRecogParams;
import com.base.asrwake.params.OfflineRecogParams;
import com.base.asrwake.params.OnlineRecogParams;
import com.base.asrwake.recog.MyRecognizer;
import com.base.asrwake.recog.listener.ChainRecogListener;
import com.base.asrwake.recog.listener.IRecogListener;
import com.base.asrwake.recog.listener.MessageStatusRecogListener;
import com.base.asrwake.sett.OnlineSetting;
import com.base.asrwake.util.MyLogger;
import com.base.commonlib.base.presenter.BasePresenter;
import com.base.commonlib.bean.TabEntity;
import com.base.commonlib.http.RealNetWorkUtil;
import com.base.commonlib.http.utils.CallBackImpl;
import com.base.commonlib.utils.RxBus2;
import com.yookey.study.bean.VoiceEvent;
import com.yookey.study.view.MainView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

import static android.app.Activity.RESULT_OK;
import static com.base.asrwake.recog.IStatus.STATUS_FINISHED;
import static com.base.asrwake.recog.IStatus.STATUS_LONG_SPEECH_FINISHED;
import static com.base.asrwake.recog.IStatus.STATUS_NONE;
import static com.base.asrwake.recog.IStatus.STATUS_READY;
import static com.base.asrwake.recog.IStatus.STATUS_RECOGNITION;
import static com.base.asrwake.recog.IStatus.STATUS_SPEAKING;
import static com.base.asrwake.recog.IStatus.STATUS_STOPPED;
import static com.base.asrwake.recog.IStatus.STATUS_WAITING_READY;


public class MainPresenter extends BasePresenter<MainView> {

    private CommonRecogParams apiParams;
    /**
     * 对话框界面的输入参数
     */
    private DigitalDialogInput input;
    private ChainRecogListener chainRecogListener;
    private Class settingActivityClass;
    /**
     * 识别控制器，使用MyRecognizer控制识别的流程
     */
    protected MyRecognizer myRecognizer;
    /*
     * 本Activity中是否需要调用离线命令词功能。根据此参数，判断是否需要调用SDK的ASR_KWS_LOAD_ENGINE事件
     */
    protected boolean enableOffline;
    /**
     * 控制UI按钮的状态
     */
    protected int status;
    protected boolean running = false;
    protected Handler handler;


    public MainPresenter(MainView view, Activity activity) {
        super(view, activity);
    }

    @Override
    public void start() {
        super.start();
        apiParams = new OnlineRecogParams();
        apiParams.initSamplePath(mActivity);
        InFileStream.setContext(mActivity);
        settingActivityClass = OnlineSetting.class;



        handler = new Handler() {

            /*
             * @param msg
             */
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                handleMsg(msg);
            }

        };
        MyLogger.setHandler(handler);

        // 基于DEMO集成第1.1, 1.2, 1.3 步骤 初始化EventManager类并注册自定义输出事件
        // DEMO集成步骤 1.2 新建一个回调类，识别引擎会回调这个类告知重要状态和识别结果
        IRecogListener listener = new MessageStatusRecogListener(handler);
        // DEMO集成步骤 1.1 1.3 初始化：new一个IRecogListener示例 & new 一个 MyRecognizer 示例,并注册输出事件
        myRecognizer = new MyRecognizer(mActivity, listener);
        if (enableOffline) {
            // 基于DEMO集成1.4 加载离线资源步骤(离线时使用)。offlineParams是固定值，复制到您的代码里即可
            Map<String, Object> offlineParams = OfflineRecogParams.fetchOfflineParams();
            myRecognizer.loadOfflineEngine(offlineParams);
        }


        chainRecogListener = new ChainRecogListener();
        // DigitalDialogInput 输入 ，MessageStatusRecogListener可替换为用户自己业务逻辑的listener
        chainRecogListener.addListener(new MessageStatusRecogListener(handler));
        myRecognizer.setEventListener(chainRecogListener); // 替换掉原来的listener



        status = STATUS_NONE;
        mView.returnStartAsrwake().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                switch (status) {
                    case STATUS_NONE: // 初始状态
                        startAsr();
                        status = STATUS_WAITING_READY;
                        updateBtnTextByStatus();
                        break;
                    case STATUS_WAITING_READY: // 调用本类的start方法后，即输入START事件后，等待引擎准备完毕。
                    case STATUS_READY: // 引擎准备完毕。
                    case STATUS_SPEAKING: // 用户开始讲话
                    case STATUS_FINISHED: // 一句话识别语音结束
                    case STATUS_RECOGNITION: // 识别中
                        stop();
                        status = STATUS_STOPPED; // 引擎识别中
                        updateBtnTextByStatus();
                        break;
                    case STATUS_LONG_SPEECH_FINISHED: // 长语音识别结束
                    case STATUS_STOPPED: // 引擎识别中
                        cancel();
                        status = STATUS_NONE; // 识别结束，回到初始状态
                        updateBtnTextByStatus();
                        break;
                    default:
                        break;
                }
            }
        });

        Disposable disposable = RxBus2.getInstance().doSubscribe(VoiceEvent.class, new Consumer<VoiceEvent>() {
            @Override
            public void accept(VoiceEvent voiceEvent) throws Exception {
                running = false;
                if (voiceEvent.getRequestCode() == 2) {
                    String message = "";
                    if (voiceEvent.getResultCode() == RESULT_OK) {
                        ArrayList results = voiceEvent.getData().getStringArrayListExtra("results");
                        if (results != null && results.size() > 0) {
                            message += results.get(0);
                        }
                    } else {
                        message+="";
                    }
                    mView.returnVoiceResult(message);
//            MyLogger.info(message);
                }

            }
        });
        RxBus2.getInstance().addSubscription(this, disposable);

        initTab();
    }



    public void initTab(){
        HashMap<String, Object> param = new HashMap<>();
        Disposable disposable = RealNetWorkUtil.get()
                .method("api-train/app/getMyCategoryList")
                .params(param)
                .build().enqueueForArray(TabEntity.SavedBean.class, new CallBackImpl<List<TabEntity.SavedBean>>() {
                    @Override
                    public void onError(int code, String msg, String errMsg) {
                        if (!TextUtils.isEmpty(msg)) {
                           if (!msg.contains("系统出错")){
                               mView.showMes(msg);
                           }
                        }
                    }
                    @Override
                    public void onNext(List<TabEntity.SavedBean> entities) {
                        if (entities!=null&&entities.size()>0) {
                            mView.returnTabList(entities);
                            //mView.returnEmptyTypeList();
                        }else {
                            mView.returnEmptyTypeList();
                            //mView.showMes("请设置分类");
                        }
                    }
                });
        mCompositeDisposable.add(disposable);

    }
    protected void handleMsg(Message msg) {
        switch (msg.what) { // 处理MessageStatusRecogListener中的状态回调
            case STATUS_FINISHED:
                if (msg.arg2 == 1) {
//                    mBinding.result.append(msg.obj.toString());
                }
                status = msg.what;
                updateBtnTextByStatus();
                break;
            case STATUS_NONE:
            case STATUS_READY:
            case STATUS_SPEAKING:
            case STATUS_RECOGNITION:
                status = msg.what;
                updateBtnTextByStatus();
                break;
            default:
                break;

        }
    }
    private void startAsr(){
        // 此处params可以打印出来，直接写到你的代码里去，最终的json一致即可。
        final Map<String, Object> params = fetchParams();

        // BaiduASRDigitalDialog的输入参数
        input = new DigitalDialogInput(myRecognizer, chainRecogListener, params);
        BaiduASRDigitalDialog.setInput(input); // 传递input信息，在BaiduASRDialog中读取,
        Intent intent = new Intent(mActivity, BaiduASRDigitalDialog.class);

        // 修改对话框样式
        // intent.putExtra(BaiduASRDigitalDialog.PARAM_DIALOG_THEME, BaiduASRDigitalDialog.THEME_ORANGE_DEEPBG);

        running = true;
        mActivity.startActivityForResult(intent, 2);
    }
    protected Map<String, Object> fetchParams() {
        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mActivity);
        //  上面的获取是为了生成下面的Map， 自己集成时可以忽略
        Map<String, Object> params = apiParams.fetch(sp);
        //  集成时不需要上面的代码，只需要params参数。
        return params;
    }
    /**
     * 开始录音后，手动点击“停止”按钮。
     * SDK会识别不会再识别停止后的录音。
     * 基于DEMO集成4.1 发送停止事件 停止录音
     */
    protected void stop() {

        myRecognizer.stop();
    }

    /**
     * 开始录音后，手动点击“取消”按钮。
     * SDK会取消本次识别，回到原始状态。
     * 基于DEMO集成4.2 发送取消事件 取消本次识别
     */
    protected void cancel() {

        myRecognizer.cancel();
    }

    @Override
    public void release() {
        super.release();
        // 如果之前调用过myRecognizer.loadOfflineEngine()， release()里会自动调用释放离线资源
        // 基于DEMO5.1 卸载离线资源(离线时使用) release()方法中封装了卸载离线资源的过程
        // 基于DEMO的5.2 退出事件管理器
        myRecognizer.release();
        // BluetoothUtil.destory(this); // 蓝牙关闭
    }
    private void updateBtnTextByStatus() {
        switch (status) {
            case STATUS_NONE:
                mView.returnStartAsrwake().setEnabled(true);
                mView.returnStartAsrwake().setEnabled(true);
                break;
            case STATUS_WAITING_READY:
            case STATUS_READY:
            case STATUS_SPEAKING:
            case STATUS_RECOGNITION:
                mView.returnStartAsrwake().setEnabled(true);
                mView.returnStartAsrwake().setEnabled(false);
                break;
            case STATUS_LONG_SPEECH_FINISHED:
            case STATUS_STOPPED:
                mView.returnStartAsrwake().setEnabled(true);
                mView.returnStartAsrwake().setEnabled(false);
                break;
            default:
                break;
        }
    }
}
